#pragma once

#include <vector>
#include "llvm/Module.h"
#include "llvm/Function.h"
#include "llvm/BasicBlock.h"
#include "llvm/Instruction.h"
#include "llvm/Type.h"
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/Instructions.h"
#include <algorithm>
#include <sys/types.h>
#include <sys/mman.h>
#include "MemoryProfiler.h"
#include "Instrumenter.h"
#include "Utils.h"
#include "ForkPreamble.h"

class EventProfiler
{
public:
	EventProfiler(Instruction *&Inst, InstrumenterBase *Instrumenter);
	void Profile(int);
	static map<Function*, EventProfiler*> ByFunc;
	set<Instruction*> NewlyFound;
private:
	bool HasHotLoads();

	Function *F;
	StubGenerator SG;
//	vector<MemoryProfiler*> &MemoryProfilers;
	InstrumenterBase *Instrumenter;

	MemoryProfiler **Begin, **End;

	vector<Instruction*> AllHotLoads;
	set<Instruction*> HotLoadsSet;
};

typedef Instrumenter<Instruction, EventProfiler> EventBase;

struct EventInstrumenter : public EventBase
{
	EventInstrumenter(Module *M, ExecutionEngine *EE);
	Value* InstrumentThis(Instruction *Inst);
};
